From 20a0e30ec5f787b68b20dfea8ad0ff95ec10cb36 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 7 Oct 2015 23:26:05 -0700 Subject: [PATCH] Auto de-dupe build scripts to link I removed this in 68014ab8 thinking it wasn't necessary, which it technically isn't for correctness but it ends up leading to absurdly long command lines to the compiler for larger projects. This also changes the `Vec` to be a `BTreeSet` to have sorting and deduplication as we go along which should be much faster than waiting to sort until the very end. --- src/cargo/ops/cargo_rustc/custom_build.rs | 12 ++--- src/cargo/ops/cargo_rustc/mod.rs | 2 +- tests/test_cargo_compile_custom_build.rs | 62 +++++++++++++++++++++++ 3 files changed, 69 insertions(+), 7 deletions(-) diff --git a/src/cargo/ops/cargo_rustc/custom_build.rs b/src/cargo/ops/cargo_rustc/custom_build.rs index 1232fa9c2..83ab98787 100644 --- a/src/cargo/ops/cargo_rustc/custom_build.rs +++ b/src/cargo/ops/cargo_rustc/custom_build.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{HashMap, BTreeSet}; use std::fs; use std::io::prelude::*; use std::path::PathBuf; @@ -35,8 +35,8 @@ pub struct BuildState { #[derive(Default)] pub struct BuildScripts { - pub to_link: Vec<(PackageId, Kind)>, - pub plugins: Vec, + pub to_link: BTreeSet<(PackageId, Kind)>, + pub plugins: BTreeSet, } /// Prepares a `Work` that executes the target as a custom build script. @@ -354,11 +354,11 @@ pub fn build_map<'b, 'cfg>(cx: &mut Context<'b, 'cfg>, return &out[unit] } - let mut to_link = Vec::new(); - let mut plugins = Vec::new(); + let mut to_link = BTreeSet::new(); + let mut plugins = BTreeSet::new(); if !unit.target.is_custom_build() && unit.pkg.has_custom_build() { - to_link.push((unit.pkg.package_id().clone(), unit.kind)); + to_link.insert((unit.pkg.package_id().clone(), unit.kind)); } for unit in cx.dep_targets(unit).iter() { let dep_scripts = build(out, cx, unit); diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index 5e5655bf8..918929187 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -30,7 +30,7 @@ mod job_queue; mod layout; mod links; -#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)] +#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy, PartialOrd, Ord)] pub enum Kind { Host, Target } #[derive(Default, Clone)] diff --git a/tests/test_cargo_compile_custom_build.rs b/tests/test_cargo_compile_custom_build.rs index 7f35237b9..3f2788d06 100644 --- a/tests/test_cargo_compile_custom_build.rs +++ b/tests/test_cargo_compile_custom_build.rs @@ -1349,3 +1349,65 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured ", compiling = COMPILING, running = RUNNING, fresh = FRESH))); }); + +test!(diamond_passes_args_only_once { + let p = project("foo") + .file("Cargo.toml", r#" + [project] + name = "foo" + version = "0.5.0" + authors = [] + + [dependencies] + a = { path = "a" } + b = { path = "b" } + "#) + .file("src/lib.rs", "") + .file("tests/foo.rs", "") + .file("a/Cargo.toml", r#" + [project] + name = "a" + version = "0.5.0" + authors = [] + [dependencies] + b = { path = "../b" } + c = { path = "../c" } + "#) + .file("a/src/lib.rs", "") + .file("b/Cargo.toml", r#" + [project] + name = "b" + version = "0.5.0" + authors = [] + [dependencies] + c = { path = "../c" } + "#) + .file("b/src/lib.rs", "") + .file("c/Cargo.toml", r#" + [project] + name = "c" + version = "0.5.0" + authors = [] + build = "build.rs" + "#) + .file("c/build.rs", r#" + fn main() { + println!("cargo:rustc-link-search=native=test"); + } + "#) + .file("c/src/lib.rs", ""); + + assert_that(p.cargo_process("build").arg("-v"), + execs().with_status(0).with_stdout(&format!("\ +{compiling} c v0.5.0 ([..] +{running} `rustc [..]` +{running} `[..]` +{running} `rustc [..]` +{compiling} b v0.5.0 ([..] +{running} `rustc [..]` +{compiling} a v0.5.0 ([..] +{running} `rustc [..]` +{compiling} foo v0.5.0 ([..] +{running} `[..]rlib -L native=test` +", compiling = COMPILING, running = RUNNING))); +}); -- 2.30.2